﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows;
using System.Windows.Controls;

namespace Kinect_Interface_Prototype_1
{
    public class GestureRectangle
    {
        public Rectangle Rectangle { get; set; }
        public double Width { get { return Rectangle.Width; } }
        public double Height { get { return Rectangle.Height; } }
        public bool Active { get; set; }

        private bool isInside;
        public bool IsInside { get { return isInside; } }
        public HandInside HandInside = HandInside.None;

        private Color inactiveColor = Colors.White;
        private Color activeColor = Colors.Yellow;
        private SolidColorBrush brush;

        private Point BasePoint;
        private double width;
        private double height;
        private double xMod;
        private double yMod;

        public GestureRectangle(int width, int height, int xMod, int yMod, bool active)
        {
            Rectangle = new Rectangle();

            this.Active = active;
            this.width = width;
            this.height = height;
            this.xMod = xMod;
            this.yMod = yMod;

            brush = new SolidColorBrush { Color = inactiveColor };

            Rectangle.Stroke = brush;
            Rectangle.StrokeThickness = 4;
        }

        public GestureRectangle(GestureRectInitialParams initialParams)
        {
            Rectangle = new Rectangle();

            this.Active = initialParams.Active;
            this.width = initialParams.Width;
            this.height = initialParams.Height;
            this.xMod = initialParams.Xmod;
            this.yMod = initialParams.Ymod;
            inactiveColor = initialParams.inactiveColor;
            activeColor = initialParams.activeColor;

            brush = new SolidColorBrush { Color = inactiveColor };

            Rectangle.Stroke = brush;
            Rectangle.StrokeThickness = 4;
        }

        public void SetParameters(Point basePoint)
        {
            BasePoint = basePoint;
            ResetRectangle();
        }

        public void SetParameters(double xBasePoint, double yBasePoint)
        {
            BasePoint = new Point(xBasePoint, yBasePoint);
            ResetRectangle();
        }

        public void SetParameters(Point basePoint, int width, int height, int xMod, int yMod)
        {
            BasePoint = basePoint;
            this.width = width;
            this.height = height;
            this.xMod = xMod;
            this.yMod = yMod;

            ResetRectangle();
        }

        public void SetParameters(double xBasePoint, double yBasePoint, int width, int height, int xMod, int yMod)
        {
            BasePoint = new Point(xBasePoint, yBasePoint);
            this.width = width;
            this.height = height;
            this.xMod = xMod;
            this.yMod = yMod;

            ResetRectangle();
        }

        private void ResetRectangle()
        {
            Rectangle.Width = width;
            Rectangle.Height = height;
            Canvas.SetLeft(Rectangle, BasePoint.X - xMod);
            Canvas.SetTop(Rectangle, BasePoint.Y - yMod); 
        }

        public bool DetermineIfLeftInside(Point leftHandPoint)
        {
            if (determineIfInside(leftHandPoint))
            {
                HandInside = HandInside.Left;
                brush.Color = activeColor;
                isInside = true;
            }
            else
            {
                HandInside = HandInside.None;
                brush.Color = inactiveColor;
                isInside = false;
            }

            return isInside;
        }

        public bool DetermineIfRightInside(Point rightHandPoint)
        {
            if (determineIfInside(rightHandPoint))
            {
                HandInside = HandInside.Right;
                brush.Color = activeColor;
                isInside = true;
            }
            else
            {
                HandInside = HandInside.None;
                brush.Color = inactiveColor;
                isInside = false;
            }

            return isInside;
        }

        public bool DetermineIfInside(Point rightHandPoint, Point leftHandPoint)
        {
            if (determineIfInside(leftHandPoint))
            {
                brush.Color = activeColor;
                isInside = true;
                HandInside = HandInside.Left;
            }
            else if (determineIfInside(rightHandPoint))
            {
                brush.Color = activeColor;
                isInside = true;
                HandInside = HandInside.Right;
            }
            else
            {
                brush.Color = inactiveColor;
                isInside = false;
                HandInside = HandInside.None;
            }

            return isInside;
        }

        public bool DetermineIfBothInside(Point rightHandPoint, Point leftHandPoint)
        {
            if (determineIfInside(leftHandPoint) && determineIfInside(rightHandPoint))
            {
                brush.Color = activeColor;
                isInside = true;
                HandInside = HandInside.Both;
            }
            else
            {
                brush.Color = inactiveColor;
                isInside = false;
                HandInside = HandInside.None;
            }

            return isInside;
        }

        private bool determineIfInside(Point handPoint)
        {
            return (handPoint.X >= BasePoint.X - xMod && handPoint.X <= BasePoint.X - (xMod - width) &&
                    handPoint.Y >= BasePoint.Y - yMod && handPoint.Y <= BasePoint.Y - (yMod - height));

        }
    }

    public class GestureRectInitialParams
    {
        public bool Active { get; set; }
        public int Width {get; set;}
        public int Height {get; set;}
        public int Xmod {get; set;}
        public int Ymod {get; set;}
        public Color activeColor { get; set; }
        public Color inactiveColor { get; set; }

        public GestureRectInitialParams(GestureRectangleType type, bool active, int width, int height, int xmod, int ymod, GestureRectangleColorSet colorSet)
        {
            IniFile settingsINI = new IniFile(Constants.SettingsINI);

            Active = active;
            Width = Int32.Parse(settingsINI.IniReadValue("Gesture Boxes", type.ToString() + "W"));
            Height = Int32.Parse(settingsINI.IniReadValue("Gesture Boxes", type.ToString() + "H"));
            Xmod = Int32.Parse(settingsINI.IniReadValue("Gesture Boxes", type.ToString() + "X"));
            Ymod = Int32.Parse(settingsINI.IniReadValue("Gesture Boxes", type.ToString() + "Y"));

            if (colorSet == GestureRectangleColorSet.MouseRectangles)
            {
                activeColor = Colors.Yellow;
                inactiveColor = Colors.White;
            }
            else if(colorSet == GestureRectangleColorSet.GestureRectangles)
            {
                activeColor = Colors.Green;
                inactiveColor = Colors.DeepSkyBlue;
            }
        }

        public static Dictionary<GestureRectangleType, GestureRectInitialParams> initialParamsDictionary = new Dictionary<GestureRectangleType, GestureRectInitialParams>
        {
            {GestureRectangleType.StartGestureRectangle, new GestureRectInitialParams(GestureRectangleType.StartGestureRectangle, true, 50, 50, 60, 40, GestureRectangleColorSet.MouseRectangles)},  
            {GestureRectangleType.RightClickGestureRectangle, new GestureRectInitialParams(GestureRectangleType.RightClickGestureRectangle, false, 75, 75, 60, 0, GestureRectangleColorSet.MouseRectangles)}, 
            {GestureRectangleType.UpperGestureRectangle, new GestureRectInitialParams(GestureRectangleType.UpperGestureRectangle, false, 50, 50, 60, 100, GestureRectangleColorSet.MouseRectangles)},
            {GestureRectangleType.LeftClickGestureRectangle, new GestureRectInitialParams(GestureRectangleType.LeftClickGestureRectangle, false, 80, 150, 190, 150, GestureRectangleColorSet.MouseRectangles)},
            {GestureRectangleType.RightHandSwipeGestureRectangle, new GestureRectInitialParams(GestureRectangleType.RightHandSwipeGestureRectangle, true, 70, 50, -50, 55, GestureRectangleColorSet.GestureRectangles)},
            {GestureRectangleType.LeftHandSwipeGestureRectangle, new GestureRectInitialParams(GestureRectangleType.LeftHandSwipeGestureRectangle, true, 55, 50, 60, 55, GestureRectangleColorSet.GestureRectangles)},
            {GestureRectangleType.CenterGestureRectangle, new GestureRectInitialParams(GestureRectangleType.CenterGestureRectangle, true, 40, 50, 3, 55, GestureRectangleColorSet.GestureRectangles)},
            {GestureRectangleType.LowerLeftGestureRectangle, new GestureRectInitialParams(GestureRectangleType.LowerLeftGestureRectangle, true, 40, 50, 3, 55, GestureRectangleColorSet.GestureRectangles)},
            {GestureRectangleType.UpperRightGestureRectangle, new GestureRectInitialParams(GestureRectangleType.UpperRightGestureRectangle, true, 40, 50, 3, 55, GestureRectangleColorSet.GestureRectangles)},
        };
    }

    public enum GestureRectangleType
    {
        StartGestureRectangle,
        RightClickGestureRectangle,
        UpperGestureRectangle,
        LeftClickGestureRectangle,
        RightHandSwipeGestureRectangle,
        LeftHandSwipeGestureRectangle,
        CenterGestureRectangle,
        LowerLeftGestureRectangle,
        UpperRightGestureRectangle
    }

    public enum GestureRectangleColorSet
    {
        MouseRectangles,
        GestureRectangles
    }

    public enum HandInside { Both, Right, Left, None };
}
